﻿/// <reference path="TsLinq.d.ts" />
/// <reference path="Linq.ts" />
/// <reference path="DefaultComparer.ts" />
//
//  Implementation for the Timespan C# class.
//
var Timespan = (function () {
    //
    //  Constructor for the timespan class.
    //
    function Timespan(milliseconds, seconds, minutes, hours, days) {
        this.msecPerSecond = 1000;
        this.msecPerMinute = 60000;
        this.msecPerHour = 3600000;
        this.msecPerDay = 86400000;
        // Internally we store the TimeSpan as Milliseconds
        this.ms = 0;
        //
        //  Returns an value wherever the two timespan are equal.
        //
        this.equals = function (ts) {
            if (!(ts instanceof Timespan)) {
                return false;
            }
            return this.ms === ts.totalMilliseconds();
        };
        //
        //  Returns an value of the total milliseconds of the given timerange.
        //
        this.totalMilliseconds = function (roundDown) {
            if (typeof roundDown === "undefined") { roundDown = false; }
            var result = this.ms;
            if (roundDown === true) {
                result = Math.floor(result);
            }
            return result;
        };
        //
        //  Returns an value of the total seconds of the given timerange.
        //
        this.totalSeconds = function (roundDown) {
            if (typeof roundDown === "undefined") { roundDown = false; }
            var result = this.ms / this.msecPerSecond;
            if (roundDown === true) {
                result = Math.floor(result);
            }
            return result;
        };
        //
        //  Returns an value of the total minutes of the given timerange.
        //
        this.totalMinutes = function (roundDown) {
            if (typeof roundDown === "undefined") { roundDown = false; }
            var result = this.ms / this.msecPerMinute;
            if (roundDown === true) {
                result = Math.floor(result);
            }
            return result;
        };
        //
        //  Returns an value of the total hours of the given timerange.
        //
        this.totalHours = function (roundDown) {
            if (typeof roundDown === "undefined") { roundDown = false; }
            var result = this.ms / this.msecPerHour;
            if (roundDown === true) {
                result = Math.floor(result);
            }
            return result;
        };
        //
        //  Returns an value of the total days of the given timerange.
        //
        this.totalDays = function (roundDown) {
            if (typeof roundDown === "undefined") { roundDown = false; }
            var result = this.ms / this.msecPerDay;
            if (roundDown === true) {
                result = Math.floor(result);
            }
            return result;
        };
        this.addDays(days);
        this.addHours(hours);
        this.addMinutes(minutes);
        this.addSeconds(seconds);
        this.addMilliseconds(milliseconds);
    }
    //
    //  Adds the given value of days.
    //
    Timespan.prototype.addDays = function (days) {
        if (!this.isNumeric(days)) {
            return;
        }
        this.ms += (days * this.msecPerDay);
        return this;
    };

    //
    //  Adds the given range of hours.
    //
    Timespan.prototype.addHours = function (hours) {
        if (!this.isNumeric(hours)) {
            return;
        }
        this.ms += (hours * this.msecPerHour);
        return this;
    };

    //
    //  Adds the given range of minutes.
    //
    Timespan.prototype.addMinutes = function (minutes) {
        if (!this.isNumeric(minutes)) {
            return;
        }
        this.ms += (minutes * this.msecPerMinute);
        return this;
    };

    //
    //  Adds the given count of miliseconds.
    //
    Timespan.prototype.addMilliseconds = function (milliseconds) {
        if (!this.isNumeric(milliseconds)) {
            return;
        }
        this.ms += milliseconds;
        return this;
    };

    //
    //  Adds the given numbers of seconds.
    //
    Timespan.prototype.addSeconds = function (seconds) {
        if (!this.isNumeric(seconds)) {
            return;
        }
        this.ms += (seconds * this.msecPerSecond);
        return this;
    };

    //
    //  Subtracts the given value of days.
    //
    Timespan.prototype.subtractDays = function (days) {
        if (!this.isNumeric(days)) {
            return;
        }
        this.ms -= (days * this.msecPerDay);
        return this;
    };

    //
    //  Subtracts the given range of hours.
    //
    Timespan.prototype.subtractHours = function (hours) {
        if (!this.isNumeric(hours)) {
            return;
        }
        this.ms -= (hours * this.msecPerHour);
        return this;
    };

    //
    //  Subtracts the given range of minutes.
    //
    Timespan.prototype.subtractMinutes = function (minutes) {
        if (!this.isNumeric(minutes)) {
            return;
        }
        this.ms -= (minutes * this.msecPerMinute);
        return this;
    };

    //
    //  Subtracts the given count of miliseconds.
    //
    Timespan.prototype.subtractMilliseconds = function (milliseconds) {
        if (!this.isNumeric(milliseconds)) {
            return;
        }
        this.ms -= milliseconds;
        return this;
    };

    //
    //  Subtracts the given numbers of seconds.
    //
    Timespan.prototype.subtractSeconds = function (seconds) {
        if (!this.isNumeric(seconds)) {
            return;
        }
        this.ms -= (seconds * this.msecPerSecond);
        return this;
    };

    //
    //  Helper method.
    //
    Timespan.prototype.isNumeric = function (input) {
        return input !== undefined && !isNaN(parseFloat(input)) && isFinite(input);
    };

    //
    //  Adds the given timespan
    //
    Timespan.prototype.add = function (ts) {
        if (!(ts instanceof Timespan)) {
            return;
        }
        this.ms += ts.totalMilliseconds();
        return this;
    };

    //
    //  Adds the given timespan
    //
    Timespan.prototype.subtract = function (ts) {
        if (!(ts instanceof Timespan)) {
            return;
        }
        this.ms -= ts.totalMilliseconds();
        return this;
    };

    //
    //  Returns the fraction of milliseconds.
    //
    Timespan.prototype.milliseconds = function () {
        return this.ms;
    };

    //
    //  Returns the fraction of seconds.
    //
    Timespan.prototype.seconds = function () {
        return Math.floor(this.ms / this.msecPerSecond) % 60;
    };

    //
    //  Returns the fraction of minutes.
    //
    Timespan.prototype.minutes = function () {
        return Math.floor(this.ms / this.msecPerMinute) % 60;
    };

    //
    //  Returns the fraction of hours.
    //
    Timespan.prototype.hours = function () {
        return Math.floor(this.ms / this.msecPerHour) % 24;
    };

    //
    //  Returns the fraction of days.
    //
    Timespan.prototype.days = function () {
        return Math.floor(this.ms / this.msecPerDay);
    };

    //
    //  Static constructor.
    //
    Timespan.fromMilliseconds = function (milliseconds) {
        return new Timespan(milliseconds);
    };

    //
    //  Static constructor.
    //
    Timespan.fromSeconds = function (seconds) {
        return new Timespan(0, seconds);
    };

    //
    //  Static constructor.
    //
    Timespan.fromMinutes = function (minutes) {
        return new Timespan(0, 0, minutes);
    };

    //
    //  Static constructor.
    //
    Timespan.fromHours = function (hours) {
        return new Timespan(0, 0, 0, hours);
    };

    //
    //  Static constructor.
    //
    Timespan.fromDays = function (days) {
        return new Timespan(0, 0, 0, 0, days);
    };
    return Timespan;
})();
